/* Dinic应用
* 1.概念
    流网络：就是有向边和点集，有向边有容量
    可行流：满足容量限制和流量守恒的流
    可行流的流量：为从源点流出的流量或者流入汇点的流量
                从源点流出的流量 - 流入源点的流量
                即 |f| = f[s, V]  - f[V, s]
    最大流：具有最大流量的可行流
    f(x, y) 是指: 从起点 x 流向 y 的流量

* 2.残留网络
    残留网络：此概念是针对可行流来定义的。不同可行流都对应着一个残留网络。
            对于残留网络，V’ = V, E’= E + E的所有反向边。
            其中，正向边的容量=原边容量 - 原边流量，反向边的容量是原边流量。
            残留网络也是一张图，残留网络有反向边，原图没有反向边
            残留网路, 考虑反向边。
    残留网络的可行流f' + 原图的可行流f = 原图的另一个可行流

    残留网络中的边定义: C'(u, v) = C(u, v) - 原图中的f(u,v) ;
    残留网络中的反向边: C'(v, u) = 原图中的f(u, v);
    现有流网络中的一个可行流f，对于其对应残留网络的一个可行流f’，有f + f’仍是原流网络中的一个可行流。而且|f + f’| = |f| + |f’|
    u 和 v 只是 图中任意的两个点;C(u，v) 代表原图中 从u到v这条边的容量是多少
        C'(u, v) 代表在残留网络中 从 u到v 这条边的容量 
    如果当前流是最大流，则一定不存在增广网络，但如果不存在增广网络，当前流未必是最大流(局部最优解)

    对于一个可行流f，如果能找到其对应残留网络中的一个可行流f’，那么就可以得到一个流量更大的可行流。不断迭代，就可以得到最大流

* 3.增广路径
    增广路径: 残留网络中一条从源点到汇点的路，这条路上的边的容量都大于0，即f'>0
             如果f的残留网络中有增广路径，则f不是最大流，流量仍可继续增加, 如果不存在，则f是最大流
  
* 4.割
    将点集分为两个部分S，T，其中源点s∈S，汇点t∈T。
    割的容量：c(S, T) = Σc(u, v), u∈S, v∈T 割边集的容量和，割的流量 只与割的划分有关
    割的流量：f(S, T) = ∑f(u, v) - ∑f(v, u), u∈S, v∈T  割边集的正向流量-割边集的反向流量
            对于不同的可行流，计算的流量是不一样的
    定理1：f(S, T) <= c(S, T)，即割的流量 <= 割的容量
    定理2：|f| = f(S, T)，即任意可行流f的流量等于任意割的流量
    定理3：|f| <= c(S, T)，即任意可行流的流量 <= 任意割的容量
    定理4：最大流最小割定理--最大流 = 最小割

* 5.算法思路
    (1)EK算法 O(nm^2) n:[1000,10000]
        邻接表存图，需要快速找到反向边，正向反向边连续加，i^1即为i边的反向边
        while()
        {
            1.找增广路径 f'
            2.更新残留网络 
        }
    (2)dinic算法 O(n^2m) n:[10000,100000]
        每次用dfs尽可能多的搜索增广路径
        1.bfs->建立分层图(避免走图中有环的死循环)
        2.dfs找出所有能增广的路径
        3.累加最大流量

        弧优化:每一次dfs是，如果之前已经选过改变，则下一次跳过改变
        cur[u]=i:u节点该从第i条边开始

* 本题:
      代表就是左部点，圆桌就是右部点。
      首先所有桌子都能坐，但是一张桌不能坐两个相同的代表，所以所有左部点分别向所有右部点连一条容量为1的边。
      源点向所有左部点连一条容量为那个点人数的边，所有右部点向汇点连一条容量为那张桌子容量的边
           
*/
#define DEBUG
#pragma GCC optimize("O1,O2,O3,Ofast")
#pragma GCC optimize("no-stack-protector,unroll-loops,fast-math,inline")
#pragma GCC target("avx,avx2,fma")
#pragma GCC target("sse,sse2,sse3,sse4,sse4.1,sse4.2,ssse3")

#include <iostream>
#include <cstring>
using namespace std;
// #define int long long
const int N = 280, M = 160, INF = 0x3f3f3f3f;

int n, m, S, T;
int h[N], e[M], ne[M], f[M], idx; //f表示容量
int q[N], d[N], cur[N]; 
// d[i]: 分层图每个点的深度
// cur[i]：弧优化

void AddEdge(int a, int b, int c)
{
    e[idx] = b, f[idx] = c, ne[idx] = h[a], h[a] = idx++;
    e[idx] = a, f[idx] = 0, ne[idx] = h[b], h[b] = idx++;
}

bool bfs()
{
    memset(d, -1, sizeof d);
    int hh = 0, tt = -1;
    q[++tt] = S, d[S] = 0, cur[S] = h[S];
    while(hh <= tt)
    {
        int u = q[hh++];
        for(int i = h[u]; ~i; i = ne[i])
        {
            int v = e[i];
            if(d[v] == -1 && f[i])
            {
                d[v] = d[u]+1;
                cur[v] = h[v];
                if(v == T) return true;
                q[++tt] = v;
            }
        }
    }
    return false;
}

int find(int u, int limit)
{
    if(u == T) return limit;
    int flow = 0;

    for(int i = cur[u]; ~i && flow < limit; cur[u] = i, i = ne[i])
    {
        int v = e[i];
        if(d[v] == d[u]+1 && f[i])
        {
            int t = find(v, min(f[i], limit-flow));
            if(!t) d[v] == -1;
            f[i]-=t, f[i^1]+=t, flow+=t;
        }
    }
    return flow;
}

int Dinic()
{
    int r = 0, flow;
    while(bfs())
        while(flow = find(S, INF)) r += flow;
    return r;
}

signed main()
{
    #ifdef DEBUG
        freopen("./in.txt", "r", stdin);
    #else
        ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    #endif

    cin >> m >> n;
    S = 0, T = m+n+1;
    memset(h, -1, sizeof h);
    int tot = 0; //总人数

    for(int i = 1; i <= m; i++) {
        int x; cin >> x;
       AddEdge(S, i, x); 
       tot += x;
    } 
    for(int i = m+1; i <= m+n; i++) {
        int x; cin >> x;
       AddEdge(i, T, x); 
    } 

    for(int i = 1; i <= m; i++)
        for(int j = m+1; j <= n+m; j++)
            AddEdge(i, j, 1);

    if(Dinic() != tot) puts("0"); 
    else{ //能坐下的人数==总人数
        puts("1");
        for(int i = 1; i <= m; i++)
        {    
            for(int j = h[i]; ~j; j = ne[j])
                if(e[j] > m && e[j] <= m+n && !f[j])
                    printf("%d ", e[j] - m);
            puts("");
        }
    }
  
    return 0;
}